﻿using AutoMapper;
using MediatR;
using Medical.Api.Write.Application.Command.Wms.WmsStorageCommand;
using Medical.Domain.Wms;
using Medical.ErrorCode;
using Medical.Interstructrue;
using Medical.Interstructrue.Base;

namespace Medical.Api.Write.Application.Handler.Wms.WmsStorageHandler
{
    /// <summary>
    /// 审批命令处理器，实现入库审批和撤销审批逻辑
    /// </summary>
    public class AuditStorageStateHandlter : IRequestHandler<AuditStorageStateCommand, ApiResult<int>>
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<AuditStorageStateHandlter> logger;
        /// <summary>
        /// AutoMapper实例
        /// </summary>
        private readonly IMapper mapper;
        /// <summary>
        /// 入库主表仓储
        /// </summary>
        private readonly IBaseRepository<WmsStorage> wmsStorageRep;
        private readonly MedicalDbContext dbContext;

        /// <summary>
        /// 构造方法，注入日志、映射和仓储依赖
        /// </summary>
        /// <param name="logger">日志</param>
        /// <param name="mapper">automapper</param>
        /// <param name="wmsStorageRep">入库仓储</param>
        public AuditStorageStateHandlter(ILogger<AuditStorageStateHandlter> logger, IMapper mapper, IBaseRepository<WmsStorage> wmsStorageRep, MedicalDbContext dbContext)
        {
            this.logger = logger;
            this.mapper = mapper;
            this.wmsStorageRep = wmsStorageRep;
            this.dbContext = dbContext;
        }

        /// <summary>
        /// 审批处理，支持入库审批和撤销审批
        /// </summary>
        /// <param name="request">审批命令，包含Id、审批状态、审批人</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>审批结果</returns>
        public Task<ApiResult<int>> Handle(AuditStorageStateCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();
            try
            {
                // 通过Id获取入库主表数据
                var storage = wmsStorageRep.GetModel(request.Id);
                if (storage == null)
                {
                    // 未找到数据，返回NotFound
                    result.Code = ApiEnums.NotFound;
                    result.Msg = $"未找到Id为{request.Id}的入库记录";
                    result.Data = 0;
                    logger.LogWarning($"审批失败：未找到Id为{request.Id}的入库记录");
                    return Task.FromResult(result);
                }

                // 如果是撤销审批，校验存放表中是否已生成存放单
                if (!request.AuditState)
                {
                    // 存放表中存在该入库单Id则不允许撤销
                    bool exists = dbContext.WmsStores.Any(s => s.StorageId == request.Id && !s.IsDeleted);
                    if (exists)
                    {
                        result.Code = ApiEnums.Fail;
                        result.Msg = "当前入库单已生成存放单，不支持撤销";
                        result.Data = 0;
                        logger.LogWarning($"撤销审批失败：Id为{request.Id}的入库单已生成存放单");
                        return Task.FromResult(result);
                    }
                }

                // 修改审批状态、审批人、审批时间
                storage.AuditState = request.AuditState;
                if (request.AuditState)
                {
                    storage.AuditName = request.AuditName;
                    storage.AuditDate = DateTime.Now;
                }
                else
                {
                    storage.AuditName = null;
                    storage.AuditDate = null;
                }

                // 更新数据库
                var updateResult = wmsStorageRep.Update(storage);
                var isApprove = request.AuditState;
                var action = isApprove ? "入库审批" : "撤销审批";

                if (updateResult > 0)
                {
                    // 审批/撤销成功
                    result.Code = ApiEnums.Success;
                    result.Msg = $"{action}成功";
                    result.Data = updateResult;
                    logger.LogInformation($"{action}成功，Id: {request.Id}");
                }
                else
                {
                    // 未更新任何数据
                    result.Code = ApiEnums.Fail;
                    result.Msg = $"{action}失败，未更新任何数据";
                    result.Data = 0;
                    logger.LogError($"{action}失败，Id: {request.Id}");
                }
            }
            catch (Exception ex)
            {
                // 异常处理，记录日志
                result.Code = ApiEnums.Error;
                result.Msg = $"入库审批异常: {ex.Message}";
                result.Data = 0;
                logger.LogError(ex, $"入库审批异常，Id: {request.Id}");
            }
            return Task.FromResult(result);
        }
    }
}
